/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.message.service.email.impl;

import cn.hutool.core.io.FileUtil;
import com.je.common.base.constants.message.SendContextType;
import com.je.common.base.exception.PlatformException;
import com.je.common.base.exception.PlatformExceptionEnum;
import com.je.common.base.service.rpc.DocumentInternalRpcService;
import com.je.common.base.service.rpc.SystemSettingRpcService;
import com.je.common.base.util.MessageUtils;
import com.je.common.base.util.StringUtil;
import com.je.message.exception.MessageSendException;
import com.je.message.model.MyAuthenticator;
import com.je.message.service.email.EmailOperationService;
import com.je.message.vo.EmailMsg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.activation.DataHandler;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * @program: jecloud-message
 * @author: LIULJ
 * @create: 2021/8/26
 * @description:
 */
@Service
public class EmailOperationServiceImpl implements EmailOperationService {

    private static final Logger logger = LoggerFactory.getLogger(EmailOperationServiceImpl.class);

    @Autowired
    private DocumentInternalRpcService documentInternalRpcService;
    @Autowired
    private SystemSettingRpcService systemSettingRpcService;

    final String EMAIL = "EMAIL";
    final String USERNAME = "JE_SYS_EMAIL_USERNAME";
    final String PASSWORD = "JE_SYS_EMAIL_PASSWORD";
    final String SERVERVALIDATE = "JE_SYS_EMAIL_SERVERVALIDATE";
    final String EMAILSSL = "JE_SYS_EMAIL_SSL";
    final String SERVERHOST = "JE_SYS_EMAIL_SERVERHOST";
    final String SERVERPORT = "JE_SYS_EMAIL_SERVERPORT";
    final String SYSTITLE = "JE_SYS_EMAIL_SENDTITLE";

    @Override
    public void sendEmail(EmailMsg msgVo) throws Exception {
        String push_platform = systemSettingRpcService.findSettingValue("JE_PUSH_PLATFORM");
        if (!push_platform.contains(EMAIL)) {
            throw new MessageSendException(MessageUtils.getMessage("message.interface.type.mismatch"));
        }
        // 判断是否需要身份认证
        MyAuthenticator authenticator = null;
        String host = systemSettingRpcService.findSettingValue(SERVERHOST);
        String port = systemSettingRpcService.findSettingValue(SERVERPORT);
        Properties pro = buildEmailConfig(host,port);
        if (Boolean.parseBoolean(systemSettingRpcService.findSettingValue(SERVERVALIDATE))) {
            //如果需要身份认证，则创建一个密码验证器
            String userName = systemSettingRpcService.findSettingValue(USERNAME);
            String password = systemSettingRpcService.findSettingValue(PASSWORD);
//            String password ="HzcZBtRkYpHWhdvZ";
            if (StringUtil.isEmpty(userName) || StringUtil.isEmpty(password)) {
                throw new PlatformException(MessageUtils.getMessage("message.account.or.password.notEmpty"), PlatformExceptionEnum.JE_MESSAGE_EMAIL_NOUSERNAME_ERROR, new Object[]{msgVo});
            }
            authenticator = new MyAuthenticator(userName, password);
        }

        // 根据邮件会话属性和密码验证器构造一个发送邮件的session
        Session sendMailSession = Session.getInstance(pro, authenticator);
        sendMailSession.setDebug(true);
        // 根据session创建一个邮件消息
        Message mailMessage = new MimeMessage(sendMailSession);
        String title = systemSettingRpcService.findSettingValue(SYSTITLE);//账户名使用系统名称
        String sendAddress = systemSettingRpcService.findSettingValue(USERNAME);
        // 创建邮件发送者地址
        InternetAddress from = new InternetAddress(sendAddress);
        if (StringUtil.isNotEmpty(title)) {
            from.setPersonal(title);
        }
        // 设置邮件消息的发送者
        mailMessage.setFrom(from);
        // 创建邮件的接收者地址，并设置到邮件消息中
        String receiveEmail = msgVo.getReceiveEmail();
        //如果是外部邮件发送
        if (receiveEmail.split(",").length > 1) {
            InternetAddress[] to = InternetAddress.parse(receiveEmail);
            mailMessage.setRecipients(Message.RecipientType.TO, to);
        } else {
            Address to = new InternetAddress(msgVo.getReceiveEmail());
            mailMessage.setRecipient(Message.RecipientType.TO, to);
        }
        //设置抄送
        if (StringUtil.isNotEmpty(msgVo.getCs())) {
            InternetAddress[] to = InternetAddress.parse(msgVo.getCs());
            mailMessage.setRecipients(Message.RecipientType.CC, to);
        }
        //设置密送
        if (StringUtil.isNotEmpty(msgVo.getMs())) {
            InternetAddress[] to = InternetAddress.parse(msgVo.getMs());
            mailMessage.setRecipients(Message.RecipientType.BCC, to);
        }
        //设置紧急状态
        String faster = "3";//默认紧急状态为普通
        if ("1".equals(msgVo.getFaster())) {
            faster = "1";
        }
        mailMessage.setHeader("X-Priority", faster);
        if ("1".equals(msgVo.getReplySign())) {
            mailMessage.setHeader("Disposition-Notification-To", sendAddress);
        }
        // 设置邮件消息的主题
        String sj = msgVo.getSubject();
        mailMessage.setSubject(sj);
        // 设置邮件消息发送的时间
        mailMessage.setSentDate(new Date());
        String contextType = "text/html";//纯文本
        if (SendContextType.TEXT.equals(msgVo.getContextType())) {
            contextType = "text/plain"; //超文本
        }
        // MiniMultipart类是一个容器类，包含MimeBodyPart类型的对象
        Multipart mainPart = new MimeMultipart();
        // 创建一个包含内容的MimeBodyPart
        MimeBodyPart mbp = new MimeBodyPart();
        // 设置HTML内容
        mbp.setContent(msgVo.getContext(), contextType + "; charset=utf-8");
        mainPart.addBodyPart(mbp);
        //发送附件
        List<String> fileNames = msgVo.getFileNames();
        List<String> fileAddress = msgVo.getAddresses();
        if (fileAddress.size() > 0 && fileNames.size() == fileAddress.size()) {
            for (Integer i = 0; i < fileNames.size(); i++) {
                boolean exists = documentInternalRpcService.exists(fileAddress.get(i));
                if (exists) {
                    File file = documentInternalRpcService.readFile(fileAddress.get(i));
                    ByteArrayDataSource source = new ByteArrayDataSource(FileUtil.getInputStream(file), "");
                    MimeBodyPart filePart = new MimeBodyPart();
                    filePart.setDataHandler(new DataHandler(source));
                    filePart.setFileName(MimeUtility.encodeText(fileNames.get(i)));
                    mainPart.addBodyPart(filePart);
                }
            }
        }
        // 将MiniMultipart对象设置为邮件内容
        mailMessage.setContent(mainPart);
        // 发送邮件
        Transport.send(mailMessage);
    }


    public Properties buildEmailConfig(String host, String port) {
        Properties properties = new Properties();
        properties.put("mail.transport.protocol", "smtp");
        String auth;
        auth = Boolean.parseBoolean(systemSettingRpcService.findSettingValue(SERVERVALIDATE)) ? "true" : "false";
        properties.put("mail.smtp.auth", auth);
        if (Boolean.parseBoolean(systemSettingRpcService.findSettingValue(EMAILSSL))) {
            properties.put("mail.smtp.ssl.enable", true);
            properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); // 使用JSSE的SSL
        }
        properties.put("mail.smtp.socketFactory.fallback", "false"); // 只处理SSL的连接,对于非SSL的连接不做处理
        properties.put("mail.smtp.host", host);
        properties.put("mail.smtp.port", port);
        properties.put("mail.smtp.socketFactory.port", port);
        properties.setProperty("mail.smtp.port", "465");
        properties.put("mail.smtp.connectiontimeout", "25000");
        properties.put("mail.smtp.timeout", "25000");
        return properties;
    }

}
